package com.d3works.apps.account.service;

import com.d3works.apps.account.db.Journal;
import com.d3works.apps.account.db.repo.JournalRepository;
import com.d3works.apps.account.db.repo.MoveRepository;
import com.d3works.db.JPA;
import com.google.inject.Inject;
import com.google.inject.persist.Transactional;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import javax.persistence.Query;

public class JournalService {
  protected JournalRepository journalRepository;

  @Inject
  public JournalService(JournalRepository journalRepository) {
    this.journalRepository = journalRepository;
  }

  /**
   * Compute the balance of the journal, depending of the account type and balance type
   *
   * @param journal Journal
   * @return The balance (debit balance or credit balance)
   */
  public Map<String, BigDecimal> computeBalance(Journal journal) {

    Map<String, BigDecimal> resultMap = new HashMap<>();

    String query =
        "select sum(self.debit),sum(self.credit)"
            + " from MoveLine self where self.move.journal.id = :journal "
            + "and self.move.ignoreInAccountingOk IN ('false', null) and self.move.statusSelect IN (:statusDaybook, :statusValidated) and self.account.accountType MEMBER OF self.move.journal.journalType.accountTypeSet";

    Query resultQuery = JPA.em().createQuery(query);

    resultQuery.setParameter("journal", journal.getId());
    resultQuery.setParameter("statusDaybook", MoveRepository.STATUS_DAYBOOK);
    resultQuery.setParameter("statusValidated", MoveRepository.STATUS_ACCOUNTED);

    Object[] resultArr = (Object[]) resultQuery.getResultList().get(0);

    resultMap.put(
        "debit", resultArr[0] != null ? new BigDecimal(resultArr[0].toString()) : BigDecimal.ZERO);
    resultMap.put(
        "credit", resultArr[1] != null ? new BigDecimal(resultArr[1].toString()) : BigDecimal.ZERO);
    resultMap.put("balance", resultMap.get("debit").subtract(resultMap.get("credit")));

    return resultMap;
  }

  @Transactional
  public void toggleStatusSelect(Journal journal) {
    if (journal != null) {
      if (journal.getStatusSelect() == JournalRepository.STATUS_INACTIVE) {
        journal = activate(journal);
      } else {
        journal = desactivate(journal);
      }
      journalRepository.save(journal);
    }
  }

  protected Journal activate(Journal journal) {
    journal.setStatusSelect(JournalRepository.STATUS_ACTIVE);
    return journal;
  }

  protected Journal desactivate(Journal journal) {
    journal.setStatusSelect(JournalRepository.STATUS_INACTIVE);
    return journal;
  }
}
